package br.com.ravi.deposito.dao;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;

import br.com.ravi.deposito.exceptions.DAOException;
import br.com.ravi.deposito.utils.hibernate.HibernateUtil;
/**
 * 
 * @author Rafael Ingaramo
 *
 * @param <T>
 */
public class GenericDAO<T extends HibernateModel> extends AbstractDAO<T> {
	private Class<?> clazz;

	public GenericDAO(Class<?> clazz) {
		this.clazz = clazz;
	}

	@Override
	public T save(T model) throws DAOException {
		Session session = HibernateUtil.getCurrentSession();
		boolean exOcurr = false;

		try {
			Transaction tx = session.beginTransaction();
			session.saveOrUpdate(model);
			tx.commit();
		} catch (Exception e) {
			exOcurr = true;
			throw new DAOException(e);
		} finally {
			HibernateUtil.closeCurrentSession(exOcurr);
		}
		return model;
	}

	@Override
	public boolean delete(T model) throws DAOException {
		Session session = HibernateUtil.getCurrentSession();
		boolean exOcurr = false;
		try {
			Transaction tx = session.beginTransaction();
			session.delete(model);
			tx.commit();
			return true;
		} catch (Exception e) {
			exOcurr = true;
			throw new DAOException(e);
		} finally {
			HibernateUtil.closeCurrentSession(exOcurr);
		}
	}

	@Override
	public boolean delete(Long model) throws DAOException {
		Session session = HibernateUtil.getCurrentSession();
		boolean exOcurr = false;
		try { 
			Transaction tx = session.beginTransaction();
			session.delete(model);
			tx.commit();
			return true;
		} catch (Exception e) {
			exOcurr = true;
			throw new DAOException(e);
		} finally {
			HibernateUtil.closeCurrentSession(exOcurr);
		}
	}

	@Override
	public T get(T model) throws DAOException {
		return get(model.getId());
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public T get(Long model) throws DAOException {
		Session session = HibernateUtil.getCurrentSession();
		boolean exOcurr = false;
		try {
			Transaction tx = session.beginTransaction();
			T obj = (T) session.get(clazz, model);
			tx.commit();
			return obj;
		} catch (Exception e) {
			exOcurr = true;
			throw new DAOException(e);
		} finally {
			HibernateUtil.closeCurrentSession(exOcurr);
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<T> list() throws DAOException {
		Session session = HibernateUtil.getCurrentSession();
		boolean exOcurr = false;
		try {
			Transaction tx = session.beginTransaction();
			Criteria criteria = session.createCriteria(clazz);
			List<T> list = criteria.list();
			tx.commit();
			return list;
		} catch (Exception e) {
			exOcurr = true;
			throw new DAOException(e);
		} finally {
			HibernateUtil.closeCurrentSession(exOcurr);
		}
	}
}